#! /usr/bin/env python
#coding=utf-8

import os
import sys

from dbinfo import ModuleMgr

class ArchInfoCollector(object):
    def __init__(self, args):
        if not args.output:
            args.output = args.input

        if not os.path.exists(args.output):
            os.makedirs(args.output)

        self._mgr = ModuleMgr(args.input, args.output)

        if getattr(args, 'mem', None):
            from dbinfo import MemDbBuilder
            mem = MemDbBuilder(self._mgr.getDBFile(), args.mem)
            mem.addAllMemInfo()
            return

        self._mgr.scan_all_files()

        if args.none:       # Do nothing, scan files only
            pass
        elif args.last:     # Update last step module summary
            self._mgr.add_all_modules()
        elif args.depends:  # Update dependencies information only
            self._mgr.add_all_dependencies()
            #self._add_all_indirects()
            self._mgr.add_symbol_names()
            self._mgr.add_all_modules()
        else:               # Update all
            self._add_all()

        print("archinfo database created successfully.")

    def _add_all(self):
        self._mgr.add_all_symbols()
        self._mgr.add_all_calls()
        self._mgr.add_all_dependencies()
        self._mgr.add_all_modules()

def createArgParser():
    import argparse
    parser = argparse.ArgumentParser(description='Collect architecture information from asset files.')
    parser.add_argument('-i', '--input',
                        help='input asset files root directory', required=True)

    parser.add_argument('-o', '--output',
                        help='output architecture information database directory', required=False)

    parser.add_argument('-s', '--scan',
                        help='Update memory information only', required=False, default=False, action='store_true')

    parser.add_argument('-e', '--none',
                        help='Update nonthing, scan elf files only', required=False, default=False, action='store_true')

    parser.add_argument('-m', '--mem',
                        help='Update memory information', required=False, default="")

    parser.add_argument('-l', '--last',
                        help='Update last step module summary information only', required=False, default=False, action='store_true')

    parser.add_argument('-d', '--depends',
                        help='Update module summary information only', required=False, default=False, action='store_true')

    parser.add_argument('-n', '--name',
                        help='Build product name', required=False)

    return parser

def scan_assets_dir(args):
    topDir = os.path.realpath(args.input)
    for root, subdirs, files in os.walk(topDir):
        for dir in subdirs:
            if dir.endswith("packages") and len(root[len(topDir)+1:].split("/")) == 2:
                args.input = root
                args.output = None
                ArchInfoCollector(args)

# python3 collector.py -i /Users/handy/Documents/work/apple/projects/OSInspect/macOS_dylibs -m /Users/handy/Documents/work/projects/python/macArchInfo/collector/vmmap/backlog_20230513_2340
if __name__ == '__main__':
    parser = createArgParser()
    args = parser.parse_args()

    # Scan
    if args.scan:
        scan_assets_dir(args)
    else:
        ArchInfoCollector(args)
